"""
AI服务工厂类
负责AI服务实例的创建、管理和生命周期控制
"""
import asyncio
import time
from typing import Dict, Any, List, Optional, Type, Union
from abc import ABC, abstractmethod
from dataclasses import dataclass
from enum import Enum
import json
import threading
from concurrent.futures import ThreadPoolExecutor
from core.logging_config import get_logger
from core.exceptions import AIServiceError, ValidationError


logger = get_logger("ai_service_factory")


class ServiceStatus(str, Enum):
    """服务状态枚举"""
    INITIALIZING = "initializing"
    READY = "ready"
    PROCESSING = "processing"
    ERROR = "error"
    STOPPED = "stopped"
    MAINTENANCE = "maintenance"


class ServiceType(str, Enum):
    """服务类型枚举"""
    # 基础分析服务
    # 区县分析服务
    INFORMATION_EXTRACTION = "information_extraction"
    # 污染类型识别服务
    POLLUTION_TYPE_RECOGNITION = "pollution_type_recognition"
    # 重复投诉识别服务
    DUPLICATE_DETECTION = "duplicate_detection"
    # 情感分析服务
    SENTIMENT_ANALYSIS = "sentiment_analysis"
    # 规范判断服务
    COMPLIANCE_CHECK = "compliance_check"
    # 信息抽取
    EXTRACT_INFO = "extract_info"
    # 报告生成服务
    REPORT_GENERATION = "report_generation"
    # 地理信息服务
    LOCATION_ANALYSIS = "location_analysis"
    # 大模型分析服务
    LLM_SERVICES = "llm_services"
    # AI 分析服务
    AI_ANALYSIS = "ai_analysis"

servers_dict = {
    "RegionalAnalysis":
        {"name": "区域分析",
         "type": ServiceType.INFORMATION_EXTRACTION,
         "parameters": {}},
    "ComplaintTypeAnalysis":
        {"name": "信访类型分析",
         "type": ServiceType.POLLUTION_TYPE_RECOGNITION,
         "parameters": {}},
    "SentimentAnalysis":
        {"name": "情感分析",
         "type": ServiceType.SENTIMENT_ANALYSIS,
         "parameters": {}},
    "ComplianceAnalysis":
        {"name": "规范性分析",
         "type": ServiceType.COMPLIANCE_CHECK,
         "parameters": {}},
    "DuplicateAnalysis":
        {"name": "规范性分析",
         "type": ServiceType.DUPLICATE_DETECTION,
         "parameters": {}},

}


@dataclass
class ServiceConfig:
    """服务配置"""
    service_type: ServiceType
    name: str
    description: str
    version: str
    enabled: bool = True
    max_concurrent_requests: int = 10
    timeout: int = 30
    retry_count: int = 3
    model_config: Dict[str, Any] = None
    api_config: Dict[str, Any] = None
    
    def __post_init__(self):
        if self.model_config is None:
            self.model_config = {}
        if self.api_config is None:
            self.api_config = {}


@dataclass
class ServiceMetrics:
    """服务指标"""
    request_count: int = 0
    success_count: int = 0
    error_count: int = 0
    average_response_time: float = 0.0
    last_request_time: Optional[float] = None
    last_error_time: Optional[float] = None
    last_error_message: str = ""
    uptime: float = 0.0
    current_queue_size: int = 0


@dataclass
class ServiceRequest:
    """服务请求"""
    request_id: str
    service_type: ServiceType
    data: Dict[str, Any]
    parameters: Dict[str, Any] = None
    priority: int = 0
    timeout: Optional[int] = None
    
    def __post_init__(self):
        if self.parameters is None:
            self.parameters = {}


@dataclass
class ServiceResponse:
    """服务响应"""
    request_id: str
    service_type: ServiceType
    success: bool
    data: Dict[str, Any] = None
    error_message: str = ""
    processing_time: float = 0.0
    metadata: Dict[str, Any] = None
    
    def __post_init__(self):
        if self.data is None:
            self.data = {}
        if self.metadata is None:
            self.metadata = {}


class AIService(ABC):
    """AI服务基类"""
    
    def __init__(self, config: ServiceConfig):
        self.config = config
        self.status = ServiceStatus.INITIALIZING
        self.metrics = ServiceMetrics()
        self.start_time = time.time()
        self._executor = ThreadPoolExecutor(max_workers=config.max_concurrent_requests)
        self._lock = threading.Lock()
        
    @abstractmethod
    async def initialize(self) -> bool:
        """初始化服务"""
        pass
    
    @abstractmethod
    async def process(self, request: ServiceRequest) -> ServiceResponse:
        """处理请求"""
        pass
    
    @abstractmethod
    async def health_check(self) -> Dict[str, Any]:
        """健康检查"""
        pass
    
    @abstractmethod
    def get_capabilities(self) -> Dict[str, Any]:
        """获取服务能力"""
        pass
    
    async def start(self) -> bool:
        """启动服务"""
        try:
            logger.info(f"启动AI服务: {self.config.name}")
            success = await self.initialize()
            
            if success:
                self.status = ServiceStatus.READY
                self.metrics.uptime = time.time() - self.start_time
                logger.info(f"AI服务启动成功: {self.config.name}")
            else:
                self.status = ServiceStatus.ERROR
                logger.error(f"AI服务启动失败: {self.config.name}")
            
            return success
            
        except Exception as e:
            self.status = ServiceStatus.ERROR
            self.metrics.last_error_time = time.time()
            self.metrics.last_error_message = str(e)
            logger.error(f"AI服务启动异常: {self.config.name}, 错误: {str(e)}")
            return False
    
    async def stop(self):
        """停止服务"""
        try:
            logger.info(f"停止AI服务: {self.config.name}")
            self.status = ServiceStatus.STOPPED
            self._executor.shutdown(wait=True)
            logger.info(f"AI服务停止成功: {self.config.name}")
            
        except Exception as e:
            logger.error(f"AI服务停止异常: {self.config.name}, 错误: {str(e)}")
    
    def update_metrics(self, success: bool, processing_time: float):
        """更新服务指标"""
        with self._lock:
            self.metrics.request_count += 1
            self.metrics.last_request_time = time.time()
            
            if success:
                self.metrics.success_count += 1
            else:
                self.metrics.error_count += 1
                self.metrics.last_error_time = time.time()
            
            # 计算平均响应时间
            total_requests = self.metrics.success_count + self.metrics.error_count
            if total_requests > 0:
                total_time = (self.metrics.average_response_time * (total_requests - 1) + processing_time)
                self.metrics.average_response_time = total_time / total_requests
    
    def get_status(self) -> Dict[str, Any]:
        """获取服务状态"""
        return {
            "name": self.config.name,
            "type": self.config.service_type.value,
            "status": self.status.value,
            "version": self.config.version,
            "enabled": self.config.enabled,
            "uptime": time.time() - self.start_time if self.status != ServiceStatus.STOPPED else 0.0,
            "metrics": {
                "request_count": self.metrics.request_count,
                "success_count": self.metrics.success_count,
                "error_count": self.metrics.error_count,
                "average_response_time": self.metrics.average_response_time,
                "success_rate": self.metrics.success_count / max(1, self.metrics.request_count),
                "last_request_time": self.metrics.last_request_time,
                "last_error_time": self.metrics.last_error_time,
                "last_error_message": self.metrics.last_error_message
            }
        }


class AIServiceFactory:
    """AI服务工厂"""
    
    def __init__(self):
        self.services: Dict[str, AIService] = {}
        self.service_configs: Dict[str, ServiceConfig] = {}
        self._lock = threading.Lock()
        self._initialized = False
        
    def register_service_type(self, service_type: ServiceType, service_class: Type[AIService]):
        """注册服务类型"""
        with self._lock:
            self.service_configs[service_type.value] = service_class
            logger.info(f"注册AI服务类型: {service_type.value}")
    
    def create_service(self, config: ServiceConfig) -> AIService:
        """创建服务实例"""
        with self._lock:
            if config.service_type.value not in self.service_configs:
                raise ValidationError(f"不支持的服务类型: {config.service_type.value}")
            
            service_class = self.service_configs[config.service_type.value]
            service = service_class(config)
            
            self.services[config.service_type] = service
            logger.info(f"创建AI服务实例: {config.name}")
            
            return service
    
    def get_service(self, service_type: str) -> Optional[AIService]:
        """获取服务实例"""
        service = self.services.get(service_type)
        if service is None:
            logger.error(f"服务不存在: {service_type}, 请先注册")
        return service
    
    def get_services_by_type(self, service_type: ServiceType) -> List[AIService]:
        """根据类型获取服务"""
        return [service for service in self.services.values() 
                if service.config.service_type == service_type]
    
    def remove_service(self, service_name: str) -> bool:
        """移除服务"""
        with self._lock:
            if service_name in self.services:
                service = self.services[service_name]
                asyncio.create_task(service.stop())
                del self.services[service_name]
                logger.info(f"移除AI服务: {service_name}")
                return True
            return False
    
    async def start_all_services(self) -> Dict[str, bool]:
        """启动所有服务"""
        results = {}
        
        for service_name, service in self.services.items():
            if service.config.enabled:
                logger.info(f"启动服务: {service_name}")
                try:
                    # 添加超时机制，防止服务启动无限等待
                    success = await asyncio.wait_for(
                        service.start(),
                        timeout=30.0  # 30秒超时
                    )
                    results[service_name] = success
                    logger.info(f"服务启动成功: {service_name}")
                except asyncio.TimeoutError:
                    logger.error(f"服务启动超时: {service_name}")
                    results[service_name] = False
                except Exception as e:
                    logger.error(f"服务启动异常: {service_name}, 错误: {str(e)}")
                    results[service_name] = False
            else:
                logger.info(f"服务已禁用，跳过启动: {service_name}")
                results[service_name] = False
        
        self._initialized = True
        return results
    
    async def stop_all_services(self):
        """停止所有服务"""
        for service_name, service in self.services.items():
            await service.stop()
        
        self._initialized = False
        logger.info("所有AI服务已停止")
    
    async def process_request(self, request: ServiceRequest) -> ServiceResponse:
        """处理请求"""
        # 查找可用的服务
        available_services = self.get_services_by_type(request.service_type)
        
        if not available_services:
            return ServiceResponse(
                request_id=request.request_id,
                service_type=request.service_type,
                success=False,
                error_message=f"没有可用的{request.service_type.value}服务"
            )
        
        # 选择负载最低的服务
        selected_service = min(available_services, 
                             key=lambda s: s.metrics.current_queue_size)
        selected_service.status = ServiceStatus.READY
        if selected_service.status != ServiceStatus.READY:
            return ServiceResponse(
                request_id=request.request_id,
                service_type=request.service_type,
                success=False,
                error_message=f"服务{selected_service.config.name}未就绪，状态: {selected_service.status.value}"
            )
        
        # 处理请求
        start_time = time.time()
        try:
            selected_service.metrics.current_queue_size += 1
            
            response = await asyncio.wait_for(
                selected_service.process(request),
                timeout=request.timeout or selected_service.config.timeout
            )
            
            processing_time = time.time() - start_time
            selected_service.update_metrics(response.success, processing_time)
            
            response.processing_time = processing_time
            return response
            
        except asyncio.TimeoutError:
            processing_time = time.time() - start_time
            selected_service.update_metrics(False, processing_time)
            
            return ServiceResponse(
                request_id=request.request_id,
                service_type=request.service_type,
                success=False,
                error_message="请求处理超时",
                processing_time=processing_time
            )
            
        except Exception as e:
            processing_time = time.time() - start_time
            selected_service.update_metrics(False, processing_time)
            
            return ServiceResponse(
                request_id=request.request_id,
                service_type=request.service_type,
                success=False,
                error_message=str(e),
                processing_time=processing_time
            )
        
        finally:
            selected_service.metrics.current_queue_size -= 1
    
    def get_service_status(self) -> Dict[str, Any]:
        """获取所有服务状态"""
        status = {
            "factory_initialized": self._initialized,
            "total_services": len(self.services),
            "services": {}
        }
        
        for service_name, service in self.services.items():
            status["services"][service_name] = service.get_status()
        
        return status
    
    async def health_check_all(self) -> Dict[str, Any]:
        """健康检查所有服务"""
        results = {
            "total_services": len(self.services),
            "healthy_services": 0,
            "unhealthy_services": 0,
            "details": {}
        }
        
        for service_name, service in self.services.items():
            try:
                health_info = await service.health_check()
                is_healthy = health_info.get("healthy", False)
                
                if is_healthy:
                    results["healthy_services"] += 1
                else:
                    results["unhealthy_services"] += 1
                
                results["details"][service_name] = {
                    "healthy": is_healthy,
                    "status": service.status.value,
                    "info": health_info
                }
                
            except Exception as e:
                results["unhealthy_services"] += 1
                results["details"][service_name] = {
                    "healthy": False,
                    "status": service.status.value,
                    "error": str(e)
                }
        
        return results
    
    def get_service_capabilities(self) -> Dict[str, Any]:
        """获取所有服务能力"""
        capabilities = {}
        
        for service_name, service in self.services.items():
            try:
                capabilities[service_name] = {
                    "type": service.config.service_type.value,
                    "name": service.config.name,
                    "description": service.config.description,
                    "version": service.config.version,
                    "capabilities": service.get_capabilities()
                }
            except Exception as e:
                logger.error(f"获取服务能力失败: {service_name}, 错误: {str(e)}")
        
        return capabilities


# 全局AI服务工厂
ai_service_factory = AIServiceFactory()


def create_service_request(service_type: ServiceType, data: Dict[str, Any], 
                          parameters: Dict[str, Any] = None, 
                          priority: int = 0, 
                          timeout: Optional[int] = None) -> ServiceRequest:
    """创建服务请求的工厂函数"""
    import uuid
    
    return ServiceRequest(
        request_id=str(uuid.uuid4()),
        service_type=service_type,
        data=data,
        parameters=parameters,
        priority=priority,
        timeout=timeout
    )

